<?php
	
	namespace Aspic\Security;
	
	use Aspic as A;
	
	/**
	* Use to protect your application
	* 
	* @Author Mallory Dessaintes <mdessaintes@gmail.com>
	* @version 1.0
	*/
	class Security {
		const ESCAPE_FUNC_ENTITIES = 'htmlentities'; // htmlentities
		const ESCAPE_FUNC_SP = 'htmlspecialchars'; // htmlspecialchars
		
		const ET_XSS = 'xss';
		const ET_JS = 'js';
		
		/**
		* Escape a string to "avoid XSS injection. You have to use urlencode (Security\Security::encodeUrl) to avoid javascript use in some tags
		* like href : href="javascript:alert(1)" which will  not be escaped by this function
		* 
		* @param string $escapeFunc The escape function to use
		* @param string $escapeQuotes Specify quotes to escape (same as the flag parameter of htmlentities and htmlspecialchars)
		* 
		* @see Security consts
		*/
		public static function escapeXss($string, $escapeFunc = self::ESCAPE_FUNC_ENTITIES, $escapeQuotes = ENT_QUOTES, $charset = 'UTF-8') {
			if($escapeFunc == self::ESCAPE_FUNC_ENTITIES) {
				$escapedString = htmlentities($string, $escapeQuotes, $charset);
			}
			elseif($escapeFunc == self::ESCAPE_FUNC_SP) {
				$escapedString = htmlspecialchars($string, $escapeQuotes, $charset);
			}
			else {
				throw new A\Exception('Unknown escape function');
			}
			
			return $escapedString;
		}
		
		public static function escapeSpecialChars($string, $escapeQuotes = ENT_QUOTES, $charset = 'UTF-8') {
			$escapedString = htmlspecialchars($string, $escapeQuotes, $charset);
			
			return $escapedString;
		}
		
		/**
		* To escape something like: alert('Do you really want to remove <?php print Security\Security::escapeJs($fileName) ?> ?');
		* Escape simple quote ', quotes " and backslash \
		*/
		public static function escapeJs($str) {
			$str = str_replace('\\','\\x5C',$str);
			$str = str_replace('\'','\\x27',$str);
			$str = str_replace('"','\\x22',$str);
			
			return $str;
		}
		
		/**
		* Shortcut for escapeXss and escapeJs
		* @param string $escapeType Security\Security::ET_XSS or Security\Security::ET_JS
		*/
		public static function escape($str, $escapeType = self::ET_XSS) {
			if($escapeType == self::ET_XSS) {
				return static::escapeXss($str);
			}
			elseif($escapeType == self::ET_JS) {
				return static::escapeJs($str);
			}
			else {
				throw new A\Exception('Escape type "'.$escapeType.'" does not exists');
			}
		}
		
		/**
		* Alias for escape
		*/
		public static function esc() {
			return call_user_func_array('static::escape', func_get_args());
		}
		
		public static function encodeUrl($string) {
			$encodedurl = urlencode($string);
			
			return $encodeUrl;
		}

		public static function getUniqueId($prefix = '') {
			$unique = uniqid($prefix, true);
			
			return $unique;
		}
		
		public static function getRandomId($salt = '') {
			$str = '';
			
			for ($i = 0; $i < 100; ++$i) {
				$str .= ord(mt_rand(0, 127));
			}
			
			$str .= $salt;
			$str = md5(sha1($str));
			
			return $str;
		}
		
		public static function getRandomString($length = 10, $useDigits = true, $useUpperCase = false) {
			$lcLetters = range('a', 'z');
			$ucLetters = range('A', 'Z');
			$digits = range(0, 9);

			$available = $lcLetters;
			
			if($useDigits) {
				$available = array_merge($available, $digits);
			}
			
			if($useUpperCase) {
				$available = array_merge($available, $ucLetters);
			}
			
			$str = '';
			
			for($i = 0; $i < $length; ++$i) {
				$str .= $available[array_rand($available)];
			}
			
			return $str;
		}
		
		/**
		* Escape a char with "\"
		*/
		public static function escapeChar($str, $char) {
			$str = str_replace('\\', '\\\\', $str);
			$str = str_replace($char, '\\'.$char, $str);
			
			return $str;
		}
		
		public static function escapeQuotes($str) {
			return static::escapeChar($str, "'");
		}
		
		public static function escapeDoubleQuotes($str) {
			return static::escapeChar($str, '"');
		}
		
	}
	
?>